﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

/// <summary>
/// 触发器消息系统
/// </summary>
public class TriggerSystem : MonoBehaviour
{
    public interface IAgent {
        long ID { get; }
        long NextTriggerUpdate { get; }
        Vector3 position { get; }
        EnumTriggerType TriggerFlag { get;}

        void SetNextTriggerUpdate(long nCurTime);
        bool HandleTrigger(TriggerRecordStruct t);
    }
    public interface IAgentGroup
    { 
        EnumTriggerType TriggerFlag { get; set; }
        long ID { get; }
        long NextTriggerUpdate { get; }
        Vector3 position { get; }
        float radius { get; }

        void SetNextTriggerUpdate(long nCurTime);
        bool HandleTrigger(TriggerRecordStruct t);
        List<TriggerRecordStruct> groupMamber { get; }
    }
    public struct TriggerRecordStruct
    {
        public EnumTriggerType triggerType;
        public long triggerID;
        public long sourceID;
        public Vector3 position;
        public float radius;
        public long timeStamp;
        public long expirationTime;
        public bool isDynamicSourcePos; 

        public TriggerRecordStruct(EnumTriggerType _eTriggerType, long _idSource, Vector3 _vPos, float _fRadius, float _fDuration, bool _bDynamicSourcePos) : this()
        {
            this.triggerType = _eTriggerType;
            this.sourceID = _idSource;
            this.position = _vPos;
            this.radius = _fRadius;
            this.expirationTime= (long)_fDuration;
            this.isDynamicSourcePos = _bDynamicSourcePos;
        }
    }
    public enum EnumTriggerType
    {
        kTrig_Explosion,
        kTrig_EnemyNear,
        kTrig_Gunfire,
    }
    public TriggerSystem()
    {
    }
    ~TriggerSystem()
    {

    }
    long RegisterTrigger(EnumTriggerType _eTriggerType, long _nPriority, long _idSource, Vector3 _vPos, float _fRadius, float _fDuration, bool _bDynamicSourcePos)
    {
        TriggerRecordStruct pTriggerRecord = new TriggerRecordStruct( _eTriggerType, _idSource, _vPos,_fRadius, _fDuration, _bDynamicSourcePos);
        triggerMap.Add(pTriggerRecord.triggerID, pTriggerRecord);
        return pTriggerRecord.triggerID; 
    }
    void RemoveTrigger(long nTriggerID)
    {
        TriggerRecordStruct t;
        if(triggerMap.TryGetValue(nTriggerID,out t))
        {
            triggerMap.Remove(nTriggerID);
        }
    }
    void Update()
    {
        IAgent pAgent = null; 
        TriggerRecordStruct pRec;
        long nCurTime = System.DateTime.Now.Ticks;

        foreach (TriggerRecordStruct t in triggerMap.Values)
        {
            TriggerRecordStruct it = t;
            if ((it.expirationTime != 0) && (it.expirationTime < nCurTime))
            {
                triggerMap.Remove(it.triggerID);
            }
            else
            {
                // 刷新动态触发器，重置时间戳
                if (it.isDynamicSourcePos)
                {
                    UpdateDynamicSourcePos(it.position);
                    it.timeStamp = nCurTime;
                }
            }
        }

        //触发智能体
        List<IAgent> agents = null;
        for (int i= agents.Count-1;i>=0;i--)
        {
            pAgent = agents[i];
            if(nCurTime  > pAgent.NextTriggerUpdate)
            {
                pAgent.SetNextTriggerUpdate(nCurTime);
                //遍历所有触发器
                foreach(TriggerRecordStruct t in triggerMap.Values)
                {
                    //检查是否响应
                    if ((pAgent.TriggerFlag & t.triggerType) == 0)
                        continue;
                    //自身不需要响应
                    if (pAgent.ID == t.sourceID)
                        continue;
                    //检查响应半径
                    if (t.radius < Vector3.Distance(pAgent.position, t.position))
                        continue;
                    //如果该智能体响应了
                    if(pAgent.HandleTrigger(t))
                    {
                        //只响应最高优先级的触发器
                        break;
                    }
                }
            }
        }
    }

    private void UpdateDynamicSourcePos(Vector3 position)
    {
        throw new NotImplementedException();
    }

    Dictionary<long, TriggerRecordStruct> triggerMap;
    bool isTriggerCriticalSection;
}
